﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage.Streams;

namespace BasicLight.Unleashed
{
    public class Encryption
    {
        /// <summary>
        /// 加密数据
        /// </summary>
        /// <param name="dataToEncrypt">要加密的字符串</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public static string AESEncrypt(string dataToEncrypt, string password)
        {
            SymmetricKeyAlgorithmProvider symmetric = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
            CryptographicKey key;
            HashAlgorithmProvider algorithm = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
            CryptographicHash cryptographic = algorithm.CreateHash();

            string encrypted = String.Empty;
            try
            {
                byte[] hash = new byte[32];
                cryptographic.Append(CryptographicBuffer.CreateFromByteArray(System.Text.Encoding.UTF8.GetBytes(password)));
                byte[] temp;
                CryptographicBuffer.CopyToByteArray(cryptographic.GetValueAndReset(), out temp);

                Array.Copy(temp, 0, hash, 0, 16);
                Array.Copy(temp, 0, hash, 15, 16);

                key = symmetric.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));
                IBuffer buffer = CryptographicBuffer.CreateFromByteArray(System.Text.Encoding.UTF8.GetBytes(dataToEncrypt));
                encrypted = CryptographicBuffer.EncodeToBase64String(CryptographicEngine.Encrypt(key, buffer, null));

                return encrypted;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 解密数据
        /// </summary>
        /// <param name="dataToDecrypt">需要解密的数据</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public static string AESDecrypt(string dataToDecrypt, string password)
        {
            SymmetricKeyAlgorithmProvider symmetric = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
            CryptographicKey key;
            HashAlgorithmProvider algorithm = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
            CryptographicHash cryptographic = algorithm.CreateHash();

            string decrypted = String.Empty;
            try
            {
                byte[] hash = new byte[32];
                cryptographic.Append(CryptographicBuffer.CreateFromByteArray(System.Text.Encoding.UTF8.GetBytes(password)));
                byte[] temp;
                CryptographicBuffer.CopyToByteArray(cryptographic.GetValueAndReset(), out temp);

                Array.Copy(temp, 0, hash, 0, 16);
                Array.Copy(temp, 0, hash, 15, 16);

                key = symmetric.CreateSymmetricKey(CryptographicBuffer.CreateFromByteArray(hash));

                IBuffer buffer = CryptographicBuffer.DecodeFromBase64String(dataToDecrypt);
                byte[] bytes;
                CryptographicBuffer.CopyToByteArray(CryptographicEngine.Decrypt(key, buffer, null), out bytes);
                decrypted = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);

                return decrypted;
            }
            catch (Exception)
            {
                return null;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="algorithm">
        /// •MD5
        /// •SHA1
        /// •SHA256
        /// •SHA384
        /// •SHA512
        /// </param>
        /// <param name="text"></param>
        /// <returns></returns>
        public static String Hash(String algorithm, String text)
        {
            IBuffer buffUtf8Text = CryptographicBuffer.ConvertStringToBinary(text, BinaryStringEncoding.Utf8);
            HashAlgorithmProvider objAlgProv = HashAlgorithmProvider.OpenAlgorithm(algorithm);
            String strAlgNameUsed = objAlgProv.AlgorithmName;
            IBuffer buffHash = objAlgProv.HashData(buffUtf8Text);

            if (buffHash.Length != objAlgProv.HashLength)
            {
                throw new Exception("There was an error creating the hash");
            }

            return CryptographicBuffer.EncodeToHexString(buffHash);
        }
    }
}
